/**
 * 
 */
package Distributive;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author CAT
 * 
 */
public class blackJackServer {

	private static final int NUMBER_OF_CLIENTS = 1;
	private static final int SERVER_PORT_NUMBER = 8189;
	private IBuffer sharedBuffer;
	private ServerSocket theServerSocket;
	private ExecutorService threadManager;

	/**
	 * Constructor for blackJackServer Initializes: threadManager sharedBuffer
	 * theServerSocket Catches IOException
	 */
	public blackJackServer() {
		this.threadManager = Executors
				.newFixedThreadPool(NUMBER_OF_CLIENTS + 1);
		this.sharedBuffer = new synchronizedBuffer();
		try {
			this.theServerSocket = new ServerSocket(SERVER_PORT_NUMBER);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 * Calls: connectWithClients() executiveProducer() and then shutdown the
	 * threadManager
	 */
	private void executeServer() {
		System.out.println("Server waiting for clients");
		this.connectWithClients();
		this.executeProducer();
		this.threadManager.shutdown();
	}

	/**
	 * Declares theCasino Initializes it to a new casino Sets it to false.
	 * 
	 * Calls: executeClient() threadManager.execute()
	 * 
	 * Catches: Exceptions to execute gracefully :)
	 */
	private void executeProducer() {
		System.out.println("inside executeProducer");
		try {
			casinoRoyale theCasino = new casinoRoyale(false);
			System.out.println("Created Casino");
			theCasino.executeClient();
			this.threadManager.execute(new gameRunner(theServerSocket.accept(),
					sharedBuffer, theCasino));
			System.out.println("Connection to producer");
		} catch (Exception e) {
			System.out.println("This is me dying gracefully");
		}

	}

	/**
	 * Declared a clientSocket and accepts a socket from the server. Calls
	 * threadManager.execute() with a new player proxy as the paramete.
	 */
	private void connectWithOneClient() {
		Socket clientSocket;
		try {
			clientSocket = theServerSocket.accept();
			System.out.println("Connected with client at: "
					+ clientSocket.getInetAddress());

			this.threadManager.execute(new playerProxy(clientSocket,
					sharedBuffer));
			System.out.println("Executing proxy for client at: "
					+ clientSocket.getInetAddress());
		} catch (Exception e) {
			System.out.println("This is me dying gracefully");
		}
	}

	/**
	 * Calls the connecWithOneClient n times, where n is the number of client
	 * connected to the server.
	 */
	private void connectWithClients() {
		for (int i = 0; i < NUMBER_OF_CLIENTS; i++) {
			this.connectWithOneClient();
		}
	}

	/**
	 * Main method for the blackJackServer. Initialized a blackJackServer called
	 * theController to a new blackJackServer() Calls executeServer() on
	 * theController.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		blackJackServer theController = new blackJackServer();
		theController.executeServer();
	}
}
